package com.ssy.lingxi.message.serviceimpl;

import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.model.vo.PageVO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.message.api.vo.response.MessageUnreadCountResponse;
import com.ssy.lingxi.message.entity.MemberMessage;
import com.ssy.lingxi.message.enums.CommonBooleanEnum;
import com.ssy.lingxi.message.enums.MessageBusinessTypeEnum;
import com.ssy.lingxi.message.enums.MessageNoticeEnum;
import com.ssy.lingxi.message.enums.MessageTypeEnum;
import com.ssy.lingxi.message.model.vo.MobileMessageDetailResponse;
import com.ssy.lingxi.message.model.vo.MobileMessageResponse;
import com.ssy.lingxi.message.repository.MemberMessageRepository;
import com.ssy.lingxi.message.service.IMobileMemberMessageService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * App系统消息服务实现类
 *
 * @author yzc
 * @version 2.0.0
 * @date 2020/10/27
 */
@Service
public class MobileMemberMessageServiceImpl extends BaseMemberMessageService implements IMobileMemberMessageService {
    @Resource
    private MemberMessageRepository memberMessageRepository;

    @Override
    public Wrapper<MessageUnreadCountResponse> unreadCount(UserLoginCacheDTO loginUser) {
        PageRequest pageRequest = PageRequest.of(1, 1, Sort.by("sendTime").descending());
        // 系统公告: 系统发送
        MemberMessage platformMessage = this.getFirstPageRecord(this.basePagePlatformMessage(pageRequest, loginUser));
        Long PlatformUnReadCount = this.countUnReadPlatformMessage(loginUser);

        // 交易通知: 商品询价, 询价报价, 采购订单
        List<String> tradeBusinessTypeList = Arrays.asList(MessageBusinessTypeEnum.IQ.getCode(), MessageBusinessTypeEnum.ORDER.getCode());
        MemberMessage tradeMessage = this.getFirstPageRecord(this.basePageBusinessMessage(pageRequest, loginUser, tradeBusinessTypeList));
        Long tradeMessageUnReadCount = this.countUnReadBusinessMessage(loginUser, tradeBusinessTypeList);

        // 采购通知: 需求发布, 需求报价
        List<String> purchaseBusinessTypeList = Collections.singletonList(MessageBusinessTypeEnum.DQ.getCode());
        MemberMessage purchaseMessage = this.getFirstPageRecord(this.basePageBusinessMessage(pageRequest, loginUser, purchaseBusinessTypeList));
        Long purchaseMessageUnReadCount = this.countUnReadBusinessMessage(loginUser, purchaseBusinessTypeList);

        // 售后通知: 退货, 换货, 维修
        List<String> afterSaleBusinessTypeList = Collections.singletonList(MessageBusinessTypeEnum.AFTER_SALE.getCode());
        MemberMessage afterSaleMessage = this.getFirstPageRecord(this.basePageBusinessMessage(pageRequest, loginUser, afterSaleBusinessTypeList));
        Long afterSaleMessageUnReadCount = this.countUnReadBusinessMessage(loginUser, afterSaleBusinessTypeList);


        // 资金通知: 授信申请, 提现审核, 提现支付
        List<String> capitalBusinessTypeList = Collections.singletonList(MessageBusinessTypeEnum.CAPITAL.getCode());
        MemberMessage capitalMessage = this.getFirstPageRecord(this.basePageBusinessMessage(pageRequest, loginUser, capitalBusinessTypeList));
        Long capitalMessageUnReadCount = this.countUnReadBusinessMessage(loginUser, capitalBusinessTypeList);

        // 促销优惠: 授信申请, 提现审核, 提现支付
        List<String> marketingBusinessTypeList = Collections.singletonList(MessageBusinessTypeEnum.MARKETING.getCode());
        MemberMessage marketingMessage = this.getFirstPageRecord(this.basePageBusinessMessage(pageRequest, loginUser, marketingBusinessTypeList));
        Long marketingMessageUnReadCount = this.countUnReadBusinessMessage(loginUser, marketingBusinessTypeList);


        // 消息提醒: 账号审核通知, 账号审核结果
        List<String> noticeBusinessTypeList = Collections.singletonList(MessageBusinessTypeEnum.MEMBER.getCode());
        MemberMessage noticeMessage = this.getFirstPageRecord(this.basePageBusinessMessage(pageRequest, loginUser, noticeBusinessTypeList));
        Long noticeMessageUnReadCount = this.countUnReadBusinessMessage(loginUser, noticeBusinessTypeList);

        MessageUnreadCountResponse response = new MessageUnreadCountResponse();
        response.setSystemMessage(platformMessage.getContent());
        response.setSystemUnread(PlatformUnReadCount);
        response.setTradeMessage(tradeMessage.getContent());
        response.setTradeUnread(tradeMessageUnReadCount);
        response.setPurchaseMessage(purchaseMessage.getContent());
        response.setPurchaseUnread(purchaseMessageUnReadCount);
        response.setAfterSaleMessage(afterSaleMessage.getContent());
        response.setAfterSaleUnread(afterSaleMessageUnReadCount);
        response.setCapitalMessage(capitalMessage.getContent());
        response.setCapitalUnread(capitalMessageUnReadCount);
        response.setMarketingMessage(marketingMessage.getContent());
        response.setMarketingUnread(marketingMessageUnReadCount);
        response.setNoticeMessage(noticeMessage.getContent());
        response.setNoticeUnread(noticeMessageUnReadCount);

        return Wrapper.success(response);
    }

    @Override
    public Wrapper<PageData<MobileMessageResponse>> pagePlatformMessage(PageVO request, UserLoginCacheDTO loginUser) {
        Pageable pageable = PageRequest.of(request.getCurrent() - 1, request.getPageSize(), Sort.by("sendTime").descending());
        Page<MemberMessage> pageList = basePagePlatformMessage(pageable, loginUser);

        List<MobileMessageResponse> resultList = pageList.stream().map(e -> {
            MobileMessageResponse mobileMessageResponse = new MobileMessageResponse();
            mobileMessageResponse.setId(e.getId());
            mobileMessageResponse.setTitle(e.getTitle());
            mobileMessageResponse.setContent(e.getContent());
            mobileMessageResponse.setUrl(e.getUrl());
            mobileMessageResponse.setStatus(e.getStatus());
            mobileMessageResponse.setSendTime(e.getSendTime());

            return mobileMessageResponse;
        }).collect(Collectors.toList());

        return Wrapper.success(new PageData<>(pageList.getTotalElements(), resultList));
    }

    @Override
    public Wrapper<PageData<MobileMessageResponse>> pageBusinessMessage(PageVO request, UserLoginCacheDTO loginUser, List<MessageBusinessTypeEnum> messageBusinessTypeEnumList) {
        List<String> businessTypeList = messageBusinessTypeEnumList.stream().map(MessageBusinessTypeEnum::getCode).collect(Collectors.toList());
        Pageable pageable = PageRequest.of(request.getCurrent() - 1, request.getPageSize(), Sort.by("sendTime").descending());
        Page<MemberMessage> pageList = basePageBusinessMessage(pageable, loginUser, businessTypeList);
        List<MobileMessageResponse> resultList = pageList.stream().map(e -> {
            MobileMessageResponse mobileMessageResponse = new MobileMessageResponse();
            mobileMessageResponse.setId(e.getId());
            mobileMessageResponse.setTitle(e.getTitle());
            mobileMessageResponse.setContent(e.getContent());
            mobileMessageResponse.setUrl(e.getAppUrl());
            mobileMessageResponse.setStatus(e.getStatus());
            mobileMessageResponse.setSendTime(e.getSendTime());
            if (MessageBusinessTypeEnum.IQ.getCode().equals(e.getBusinessType())) {
                int index = MessageNoticeEnum.productInquiryPre.length();
                String number = e.getContent().substring(index, index + 9);
                if (number.startsWith("XJ")){
                    mobileMessageResponse.setCode(MessageBusinessTypeEnum.XJ.getCode());
                }else {
                    mobileMessageResponse.setCode(MessageBusinessTypeEnum.BJ.getCode());
                }
                mobileMessageResponse.setNumber(number);
            } else if (MessageBusinessTypeEnum.ORDER.getCode().equals(e.getBusinessType())) {
                int index = MessageNoticeEnum.sellOrderPre.length();
                mobileMessageResponse.setCode(MessageBusinessTypeEnum.ORDER.getCode());
                mobileMessageResponse.setNumber(e.getContent().substring(index, index + 9));
            }
            return mobileMessageResponse;
        }).collect(Collectors.toList());
        return Wrapper.success(new PageData<>(pageList.getTotalElements(), resultList));
    }

    @Override
    public Wrapper<MobileMessageDetailResponse> getMemberMessage(Long id, UserLoginCacheDTO loginUser) {
        MemberMessage memberMessage = memberMessageRepository.findById(id).orElse(null);
        if (Objects.isNull(memberMessage)) {
            return Wrapper.fail(ResponseCode.MSG_MESSAGE_NOT_FOUND);
        }

        MobileMessageDetailResponse response = new MobileMessageDetailResponse();
        response.setId(memberMessage.getId());
        response.setTitle(memberMessage.getTitle());
        response.setContent(memberMessage.getContent());
        response.setSendTime(memberMessage.getSendTime());

        return Wrapper.success(response);
    }

    /**
     * 查询平台发送的消息
     *
     * @param pageable  分页参数
     * @param loginUser 登录用户信息
     * @return 返回结果
     */
    private Page<MemberMessage> basePagePlatformMessage(Pageable pageable, UserLoginCacheDTO loginUser) {
        // 拉取平台消息
        this.basePullMainMessage(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserId());

        Specification<MemberMessage> specification = (root, query, cb) -> {
            List<Predicate> list = new ArrayList<>();

            list.add(cb.equal(root.get("recMemberId"), loginUser.getMemberId()));
            list.add(cb.equal(root.get("recRoleId"), loginUser.getMemberRoleId()));
            list.add(cb.equal(root.get("recUserId"), loginUser.getUserId()));
            list.add(cb.equal(root.get("type"), MessageTypeEnum.PLATFORM.getCode()));

            Predicate[] p = new Predicate[list.size()];
            return query.where(list.toArray(p)).getRestriction();
        };

        return memberMessageRepository.findAll(specification, pageable);
    }

    /**
     * 查询平台消息发送的消息数量
     *
     * @param loginUser 登录用户信息
     * @return 返回结果
     */
    private Long countUnReadPlatformMessage(UserLoginCacheDTO loginUser) {
        Specification<MemberMessage> specification = (root, query, cb) -> {
            List<Predicate> list = new ArrayList<>();

            list.add(cb.equal(root.get("recMemberId"), loginUser.getMemberId()));
            list.add(cb.equal(root.get("recRoleId"), loginUser.getMemberRoleId()));
            list.add(cb.equal(root.get("recUserId"), loginUser.getUserId()));
            list.add(cb.equal(root.get("type"), MessageTypeEnum.PLATFORM.getCode()));
            list.add(cb.equal(root.get("status"), CommonBooleanEnum.NO.getCode()));

            Predicate[] p = new Predicate[list.size()];
            return query.where(list.toArray(p)).getRestriction();
        };

        return memberMessageRepository.count(specification);
    }

    /**
     * 查询业务消息发送的消息
     *
     * @param pageable  分页参数
     * @param loginUser 登录用户信息
     * @return 返回结果
     */
    private Page<MemberMessage> basePageBusinessMessage(Pageable pageable, UserLoginCacheDTO loginUser, List<String> businessTypeList) {
        Specification<MemberMessage> specification = (root, query, cb) -> {
            List<Predicate> list = new ArrayList<>();

            list.add(cb.equal(root.get("recMemberId"), loginUser.getMemberId()));
            list.add(cb.equal(root.get("recRoleId"), loginUser.getMemberRoleId()));
            list.add(cb.equal(root.get("recUserId"), loginUser.getUserId()));
            list.add(cb.in(root.get("businessType")).value(businessTypeList));

            Predicate[] p = new Predicate[list.size()];
            return query.where(list.toArray(p)).getRestriction();
        };

        return memberMessageRepository.findAll(specification, pageable);
    }

    /**
     * 查询业务消息发送的消息数量
     *
     * @param loginUser        登录用户信息
     * @param businessTypeList 业务类型
     * @return 返回结果
     */
    private Long countUnReadBusinessMessage(UserLoginCacheDTO loginUser, List<String> businessTypeList) {
        Specification<MemberMessage> specification = (root, query, cb) -> {
            List<Predicate> list = new ArrayList<>();

            list.add(cb.equal(root.get("recMemberId"), loginUser.getMemberId()));
            list.add(cb.equal(root.get("recRoleId"), loginUser.getMemberRoleId()));
            list.add(cb.equal(root.get("recUserId"), loginUser.getUserId()));
            list.add(cb.in(root.get("businessType")).value(businessTypeList));
            list.add(cb.equal(root.get("status"), CommonBooleanEnum.NO.getCode()));

            Predicate[] p = new Predicate[list.size()];
            return query.where(list.toArray(p)).getRestriction();
        };

        return memberMessageRepository.count(specification);
    }

    private MemberMessage getFirstPageRecord(Page<MemberMessage> page) {
        return page.stream().findFirst().orElse(new MemberMessage());
    }
}